<?php
namespace Notify\Controller;

class NotifyController extends \Think\Controller
{
	const PAY_LOG_TYPE = 19;
	
	/**
	 * 19pay异步通知
	 */
	public function nineteenPay()
	{
		$error = false;
		// 只支持POST请求
		if(!IS_POST) $error = '请求方式出错';
		
		$param = I('post.');

		if(!$param['status']) {
			$error = 'status参数错误';
		} else if(strtoupper($param['status']) === 'FAIL') {
			$error = '支付失败status=fail,error_code='.$param['error_code'];
		} else if(!$param['verifyString']) {
			$error = 'verifyString参数错误';
		} else if(!$param['version_id']) {
			$error = 'version_id参数错误';
		} else if(!$param['merchant_id']) {
			$error = 'merchant_id参数错误';
		} else if(!$param['order_id']) {
			$error = 'order_id参数错误';
		} else if(!$param['order_date']) {
			$error = 'order_date参数错误';
		} else if(!$param['order_sub_time']) {
			$error = 'order_sub_time参数错误';
		} else if(!$param['amount'] || $param['amount'] <= 0) {
			$error = 'amount参数错误';
		} else if(!$param['mp_orderid']) {
			$error = 'mp_orderid参数错误';
		}
		
		if($error) {
			record_error_log(__FILE__, __LINE__, $error, null, null, self::PAY_LOG_TYPE);
			die('N');
		}
		
		// 保存签名 
		$verifyStr1 = $param['verifyString'];
		unset($param['verifyString']);
		ksort($param);
		
		// 组装字符串并生成签名
		$str = '';
		foreach($param as $key => $val) {
			$str .= $key . '=' . $val . '&';
		}
		
		$str = substr($str, 0, strlen($str) - 1);
		$verifyStr2 = strtolower(md5($str));
		
		//判断签名是否一致
		if($verifyStr1 !== $verifyStr2) {
			record_error_log(__FILE__, __LINE__, '签名错误', null, null, self::PAY_LOG_TYPE);
			die('N');
		}
	
		// 支付成功的业务逻辑
		$res = $this->payInternal($param['mp_orderid']);
		if(!$res) die('N');
		die('Y');
	}
	
	/**
	 * 成功支付业务处理
	 */
	private function payInternal($orderNo)
	{
		$investModel = D('Invest');
		//查询定单信息
		$where = array('order_no'=>$orderNo);
		$where['status'] = 2;
		$invest = $investModel->where($where)->find();
		if(!$invest) return false;
		
		//查询基金信息
		$fund = M('Fund')->where(array('id'=>$invest['fund_id'],'status'=>1))->find();
		if(!$fund) return false;
		
		// 查询用户信息
		$user = M('User')->where(array('id'=>$invest['user_id']))->find();
		if(!$user) return false;
		
		// 开启事务 
		$investModel->startTrans();
		$flag = true;
		
		try {
			//更新合同状态
			$res = M('UserContract')->where(array('order_no'=>$orderNo,'status'=>0))->save(array('status' => 1));
			if(!$res) throw new \Exception('合同状态更新失败');
			
			//添加定单日志
			$lData['invest_id'] = $invest['id'];
			$lData['note'] = '支付成功';
			$lData['type'] = 0;
			$res = D('InvestLog')->addLog($lData);
			if($res['error'] === 1) throw new \Exception($res['info']);
			
			//判断用户是否通过实名认证
			if(!($user['bit_status'] & 1)) {
				$realnameStatus = $user['bit_status'] | 1;
				$res = M('User')->where(array('id'=>$invest['user_id']))->save(array('bit_status'=>$realnameStatus));
				if(!$res) throw new \Exception('实名认证更新失败');
			}
			
			//更新定单
			$data['status'] = 1;
			$data['effective_time'] = strtotime(date('Y-m-d'));
			$stdTime = $fund['std_time'] . ' day';
			if($fund['std_unit'] == 2) $stdTime = $fund['std_time'] . ' month';
			if($fund['std_unit'] == 3) $stdTime = $fund['std_time'] . ' year';
			$data['end_time'] = strtotime($stdTime, $data['effective_time']);
			$res = $investModel->where(array('id'=>$invest['id']))->save($data);
			if(!$res) throw new \Exception('定单更新失败');
			
			$investModel->commit();
		} catch (\Exception $e) {
			$investModel->rollback();
			$flag = false;
			record_error_log(__FILE__, __LINE__, $e->getMessage(), null, null, self::PAY_LOG_TYPE);
		}
		
		return $flag;
	}
}